using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using softDemo.Demain.log;
using softDemo.Demain.Responsity;

namespace soft.softDemo.basic.Filter
{

    // 全局异常捕获
    // 我们可以通过继承IAsyncExceptionFilter、IExceptionFilter接口来实现全局异常捕获
    // IAsyncExceptionFilter与IExceptionFilter区别：同步、异步。


    //注意：使用IAsyncExceptionFilter，必须要先下载程序集 Microsoft.AspNetCore.Mvc。
    public class MyCouterFilter : IAsyncExceptionFilter
    {
        private readonly IResponsity<Log> _logger;       //定义属性，接收Responsity<Log>实例

        public MyCouterFilter(IResponsity<Log> logger)  //构造函数依赖注入，获取Responsity<Log>实例
        {
            _logger = logger;
        }

        // 实现IAsyncExceptionFilter内的函数OnExceptionAdync()。
        // 在该函数内可以自定义回传的异常信息。
        // 在OnExcetpionAsync内就收一个ExceptionContext类型参数，我们可以通过ExceptionContext参数来设置自定义的返回结果
        public Task OnExceptionAsync(ExceptionContext context)
        {
            //ExceptionContext是一个实例对象，其有两个比较重要的属性Exception、ExceptionHandled 
            // 1、通过 Exception属性，我们可以获取到异常实例。
            // 2、通过ExceptionHandled属性，我们可以获取到当前的异常是否已处理。

            if (context.ExceptionHandled == false)  //如果该异常没有处理，则进入
            {
                // 获取异常信息
                string msg = context.Exception.Message;
                // 获取异常实例,并转换为字符串形式。
                string exception = context.Exception.ToString();

                // 将异常信息与异常实例写入数据库中的Log表中。
                _logger.Add(new Log
                {
                    IsDelete = false,
                    Message = msg,
                    Exception = exception,
                    CreateAt = System.DateTime.Now,
                    UpdateAt = System.DateTime.Now
                });
            }

            // 最后，将该异常标记为已处理。
            context.ExceptionHandled = true;

            return Task.CompletedTask;      //可以去看Task用法。
        }

        // 现在异常过滤器已经做好了，然后就是考虑如何去使用该异常过滤器了。
        // 在Startup.cs中将该过滤器注册为全局的控制器服务中去。
        // 全局的控制器服务：不论哪个控制器中发生了异常，都会经过该异常过滤器处理。
    }
}